//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <ddk.h>
#include <bulverde.h>
#include "wm9713.h"
#include "pen.h"

ECode Ac97_Read(UInt8 Offset, UInt16 * Data);
ECode Ac97_Write(UInt8 Offset, UInt16  Data);

static __inline void wm9712_reg_write(unsigned int reg, unsigned int val)
{
    Ac97_Write(reg, (unsigned short)val);
}

static __inline unsigned int wm9712_reg_read(unsigned int reg)
{
    unsigned short val = 0;
	Ac97_Read(reg, &val);
	return val;
}

void wm9712_touch_enable(void)
{
    unsigned int adcControl2;

    adcControl2 = wm9712_reg_read(WM9712_DIGITISER_CONTROL2);
    adcControl2 |= WM9712_TOUCHCTRL2_PRP_PDW_3;
    wm9712_reg_write(WM9712_DIGITISER_CONTROL2, adcControl2);
}

void WM9712_clear_sticky( void )
{
    wm9712_reg_write(WM9712_DIGITISER_GSTATUS, 0 ); //0x800 );
}

void wm9712_configure_GPIO( )
{
	unsigned int adcControl2;

	adcControl2 = wm9712_reg_read(WM9712_DIGITISER_GCONF);
	adcControl2 &= ~(WM9712_GPIOBIT_IRQ);//output
	wm9712_reg_write(WM9712_DIGITISER_GCONF, adcControl2 );

	adcControl2 = wm9712_reg_read(WM9712_DIGITISER_GPTYPE);
	adcControl2 |= WM9712_GPIOBIT_IRQ;//Active high
	adcControl2 |= WM9712_GPIOBIT_PENDOWN;//Active high
	wm9712_reg_write(WM9712_DIGITISER_GPTYPE, adcControl2);

	adcControl2 = wm9712_reg_read(WM9712_DIGITISER_GSTICKY);
	adcControl2 |= WM9712_GPIOBIT_IRQ;//sticky
	adcControl2 |= WM9712_GPIOBIT_PENDOWN;//sticky
	wm9712_reg_write(WM9712_DIGITISER_GSTICKY, adcControl2);

	adcControl2 = wm9712_reg_read(WM9712_DIGITISER_GWAKEUP);
	adcControl2 |= WM9712_GPIOBIT_IRQ;//wake up
	adcControl2 |= WM9712_GPIOBIT_PENDOWN;//wake up
	wm9712_reg_write(WM9712_DIGITISER_GWAKEUP, adcControl2);

	adcControl2 = wm9712_reg_read(WM9712_DIGITISER_GSHARE);
	adcControl2 &= ~(WM9712_GPIOBIT_IRQ);//select
	wm9712_reg_write(WM9712_DIGITISER_GSHARE, adcControl2);

	adcControl2 = wm9712_reg_read(WM9712_DIGITISER_AFUNC1);

	adcControl2 |= 0x2;//GPIO wake up

	wm9712_reg_write(WM9712_DIGITISER_AFUNC1, adcControl2);
	wm9712_reg_write(0x58,0xFF00);//andy
	wm9712_reg_write(0x74,0x0006);//andy
	wm9712_reg_write(0x76,0x0036);//andy
	wm9712_reg_write(0x3C,0x1aff);//andy

	wm9712_touch_enable();
	WM9712_clear_sticky();

}

/*
 * This configures the WM9712 layer depending on the machine type
 * we're running on.  The WM9712 drivers should not contain any
 * machine dependencies.
 *
 * We can get rid of some of these dependencies by using existing
 * facilities provided by the kernel - namely IRQ probing.  The
 * machine specific files are expected to setup the IRQ levels on
 * initialisation.  With any luck, we'll get rid of all the
 * machine dependencies here.
 */
int wm9712_configure()
{
	//int irq;

	GPDR3 &= ~(0x1 << 20); // set GPIO-116 pin as input
	GEDR3 |= (0x1 << 20); // clear irq status register

	//irq = IRQ_GPIO(116); // GPIO-116 irq

    GRER3 |= (0x1 << 20);//rising edge

	return 0;
}

unsigned int sampleADC(unsigned int *sample, unsigned int axis)
{
	unsigned int adcControl1 = 0;
	unsigned int adcDataReg;

	/* set polling mode, axis and delay */
	if (axis == WM9712_ADC_X)
	    adcControl1 |= (WM9712_TOUCHCTRL1_ADR_X | WM9712_TOUCHCTRL1_POLL);
	else if (axis == WM9712_ADC_Y)
	    adcControl1 |= (WM9712_TOUCHCTRL1_ADR_Y | WM9712_TOUCHCTRL1_POLL);
	else
	    adcControl1 |= (WM9712_TOUCHCTRL1_PRESSURE | WM9712_TOUCHCTRL1_POLL);

    wm9712_reg_write(0x74, adcControl1);

	/* wait for sample completion, check polling bit to reset itself
	 * upon completion of the conversion
	 */
	do {
		adcControl1 = wm9712_reg_read(0x74);
	} while( adcControl1 & WM9712_TOUCHCTRL1_POLL );

	adcDataReg = wm9712_reg_read(WM9712_DIGITISER_DATA);
	*sample = adcDataReg & WM9712_DATA_VAL; // lowest 12 bits

	if(!(adcDataReg & WM9712_DATA_PENDOWN)) {
		*sample = 0;
		return 0;
	}
	return 1;
}
